import java.awt.*; // This library includes the graphics functions
import java.applet.Applet; // This library is needed for applets
import java.awt.event.*; // This library is needed for event handling
public class Star extends Applet implements Runnable {
// This creates the variable starThread of type Thread
// using threads allows for different tasks to happen
// at the same time.
Thread starThread;
// The variable out is used as a flag as to whether or not the
// mouse cursor is in the game.
// if out = 1 then the game is paused
public int out = 0;
// The following variables are used obvious
public boolean gameover = false;
public int kills = 0;
public int health = 100;
// This variable modifies how long the explosion sprite should be displayed
public int deathWait = 12;
// These three variable are used to determine the random time between enemies appearing
public int randomSeed = 50;
public int randomTime = (int) (((Math.random() * randomSeed) + 1) + 50);
public int timeInc = 0;
// These arrays are used to hold varius data concerning the enemies
// These could be grouped into a single object
public int enemyX[];
public int enemyY[];
public int enemySpeed[];
public int enemyOpen[];
public int enemyType[];
public int enemyDeath[];
public int enemySlope[];
// These arrays contain data about the bullets being fired from the ship
// again they could be grouped into a single object
public int bX[];
public int bY[];
public int bOpen[];
public int bType[];
public int numBullets = 20;
public int numStars = 30;
public int bulletShot = 0;
// These are for the star field
public int starsX[];
public int starsY[];
// These can modify the screen size
public int xSize = 640, ySize = 480;
// These variables can be changed to speed up or slow down the game
public int speed = 6;
public int sleepTime = 8;
// These are the coordinates for the space ship
public int shipX = (xSize / 2) - 17;
public int shipY = ySize - 80;
// This is used for image buffering
Image imageBuffer;
// These variables hold the images for the game
Image ship;
Image enemy1;
Image enemy2;
Image ex;
Image b1;
Image b2;
// This method initializes the some of the variables to be use in the game
public void init () {
setSize(xSize, ySize);
enemyX = new int [5]; // The number 5 indicates that there are 5 enemies that are going to be cycled through
enemyY = new int [5];
enemySpeed = new int [5];
enemyOpen = new int [5];
enemyType = new int [5];
enemyDeath = new int [5];
enemySlope = new int [5];
bX = new int [numBullets];
bY = new int [numBullets];
bOpen = new int [numBullets];
bType = new int [numBullets];
ship = getImage(getCodeBase(), "ship.gif"); // This is how easy it is to load a graphic
enemy1 = getImage(getCodeBase(), "enemy1.gif");
enemy2 = getImage(getCodeBase(), "enemy2.gif");
ex = getImage(getCodeBase(), "ex.gif");
b1 = getImage(getCodeBase(), "b1.gif");
b2 = getImage(getCodeBase(), "b2.gif");
initStars();
repaint();
addMouseListener(new LocalMouseListener(this));
addMouseMotionListener(new LocalMouseMotionListener(this));
}
// When the applet starts the thread starts!
public void start() {
if(starThread==null) {
starThread = new Thread(this);
starThread.setPriority(5);
starThread.start();
}
}
// When the applet stops the thread stops!
public void stop() {
if(starThread!=null) {
starThread.stop();
starThread = null;
}
}
// This will create a new enemy to scroll down the screen
// Again there are only really 5 enemies that are cycled through
// then enemyOpen[] array determines whether an enemy is currently "alive"
public void newEnemy() {
int r = 0;
for (int a = 0; a < 5; a++) {
if (r == 0 & enemyOpen[a] == 0) {
enemyOpen[a] = 1;
r = 1;
enemySpeed[a] = (int) ((Math.random() * 5) + 1);
enemyType[a] = (int) ((Math.random() * 2) + 1);
enemySlope[a] = (int) (((Math.random() * 3) + 1) - 1);
int t = (int) ((Math.random() * 2) + 1);
if (t == 1) {
enemySlope[a] = -(enemySlope[a]);
}
enemyX[a] = (int) ((Math.random() * (xSize - 32)) + 1);
enemyY[a] = -32;
randomTime = (int) (((Math.random() * randomSeed) + 1) + 50);
timeInc = 0;
}
}
}
// This is the heart of the program
// It runs over and over again while the thread is active and the program is going!
public void run() {
while (true) {
if (health == 0) {
kills = 0;
health = 100;
gameover = true;
}
timeInc++; // This will call the newEnemy method if a random time has elapsed for a new enemy to appear
if (timeInc == randomTime) {
newEnemy();
}
moveEnemys(); // These methods update the sprites positions
moveStars();
moveBullets();
collisions();
prepareImageBuffer(); // This method prepares the screen to be drawn
repaint(); // This draws the graphics to the screen
try { // This pauses the game
starThread.sleep(sleepTime);
}
catch(InterruptedException e) {}
}
}
// This creates the starfield in the background
public void initStars () {
imageBuffer = createImage(xSize, ySize);
starsX = new int[numStars];
starsY = new int[numStars];
for (int a = 0; a < numStars; a++) {
starsX[a] = (int) ((Math.random() * xSize - 1) + 1);
starsY[a] = (int) ((Math.random() * ySize - 1) + 1);
}
}
// This method moves the enemies
public void moveEnemys () {
for (int i = 0; i < 5; i++) {
if (enemyX[i] + enemySlope[i] < 0) { // These statements move the enemies haphazardly left and right
enemySlope[i] *= -1;
}
if (enemyX[i] + enemySlope[i] > xSize - 32) {
enemySlope[i] *= -1;
}
enemyX[i] += enemySlope[i];
int a = (int) ((Math.random() * 150) + 1);
if (a == 3) {
enemySlope[i] *=-1;
}
if (a == 5 & Math.abs(enemySlope[i]) < 8) {
enemySlope[i] *= -2;
}
if (a ==6 & Math.abs(enemySlope[i]) > 0) {
enemySlope[i] /= -2;
}
if (enemyOpen[i] > 0) {
if (enemyOpen[i] == 2) {
if (enemyDeath[i] == deathWait) {
enemyOpen[i] = 0;
}
else {
enemyDeath[i]++;
}
}
if (enemyY[i] > ySize) {
enemyOpen[i] = 0;
}
else {
enemyY[i] += enemySpeed[i] + (speed - 6); // This moves the enemy down
}
}
}
}
// This method simply tests for collisions between the sprites on the screen
public void collisions () {
if (out == 0) {
for (int i = 0; i < 5; i++) {
for (int a = 0; a < numBullets; a++) {
if (bOpen[a] == 1) {
if (bY[a] > shipY & bY[a] < shipY + 32) {
if (bX[a] > shipX & bX[a] < shipX + 32) {
bOpen[a] = 0;
health -= 5;
}
}
}
if (bOpen[a] == 1 & enemyOpen[i] == 1) {
if (bY[a] > enemyY[i] & bY[a] < enemyY[i] + 32) {
if (bX[a] > enemyX[i] & bX[a] < enemyX[i] + 32) {
enemyDeath[i] = 0;
enemyOpen[i] = 2;
bOpen[a] = 0;
kills++;
}
}
}
}
if (enemyOpen[i] == 1) {
if ((shipX + 32 > enemyX[i]) & (shipX < enemyX[i] + 32)) {
if ((shipY + 32 > enemyY[i]) & (shipY < enemyY[i] + 36)) {
enemyDeath[i] = 0;
enemyOpen[i] = 2;
health -= 5;
}
}
}
}
}
}
// If a bullet has been fired this will move it
public void moveBullets () {
for (int i = 0; i < numBullets; i++) {
if (bOpen[i] == 1) {
if (bY[i] < 5) {
bOpen[i]=0;
}
else {
if (bType[i] == 1) {
bY[i] -= 2;
}
else {
bY[i] -= 4;
}
}
}
}
}
// If a star in the background reaches the bottome then it will go back to the top
public void moveStars () {
for (int a = 0; a < numStars; a++) {
if (starsY[a] + 1 > ySize - (speed * 2 )) {
starsY[a] = 0;
}
else {
starsY[a] += speed;
}
}
}
// This prepares the graphics to being drawn to the screen
public void prepareImageBuffer() {
Graphics g = imageBuffer.getGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, xSize, ySize);
g.setColor(Color.blue);
for (int a = 0; a < numStars; a++) {
g.drawRect(starsX[a], starsY[a], 1, 1);
}
g.setColor(Color.yellow);
g.drawString("Kills = " + kills, 5, 20);
g.drawString("Health = " + health + "%", xSize - 80, 20);
if (out == 0) {
if (gameover == true) {
g.drawString("Game Over", (xSize / 2) - 15, ySize / 2);
}
}
else {
g.drawString("Game Paused", (xSize / 2) - 23, ySize / 2);
}
g.setXORMode(Color.black); // This allows sprites to preserve the background
for (int q = 0; q < numBullets; q++) {
if (bOpen[q] == 1) {
if (bType[q] == 1) {
g.drawImage(b1, bX[q] - (b1.getWidth(this) / 2), bY[q] - b1.getHeight(this), this);
}
else {
g.drawImage(b2, bX[q] - (b1.getWidth(this) / 2), bY[q] - b1.getHeight(this), this);
}
}
}
for (int i = 0; i < 5; i++) {
if (enemyOpen[i] == 2) {
g.drawImage(ex, enemyX[i], enemyY[i], this);
}
if (enemyOpen[i] == 1) {
if (enemyType[i] == 1) {
g.drawImage(enemy1, enemyX[i], enemyY[i], this);
}
else {
g.drawImage(enemy2, enemyX[i], enemyY[i], this);
}
}
}
g.drawImage(ship, shipX, shipY, this);
}
// This draws the graphics to the screen
public void paint (Graphics g) {
g.drawImage(imageBuffer, 0, 0, this);
}
// This overides the update method for smooth animation
public void update(Graphics g) {
paint(g);
}
// This class listens for the mouse to be moved or dragged
// when the mouse is dragged than a bullet is fired!
// Also, when shift is held down then the ship goes wherever the mouse goes.
// If alt is held down than a different bullet is fired!
class LocalMouseMotionListener implements MouseMotionListener {
Star parent;
LocalMouseMotionListener(Star p) {parent = p;}
public void mouseDragged (MouseEvent e) {
int r = 0;
if (bulletShot == 4) {
if (gameover == true) {gameover = false;}
for (int a = 0; a < numBullets; a++) {
if (bOpen[a] == 0 & r == 0) {
if (e.isAltDown() == true) {
bType[a] = 2;
}
else {
bType[a] = 1;
}
bX[a] = shipX + 16;
bY[a] = shipY - 1;
bOpen[a] = 1;
r = 1;
}
}
bulletShot = 0;
}
else {
bulletShot++;
}
int xx = e.getX();
int yy = e.getY();
if (yy < shipY - 32) {
speed = 9;
}
else {
speed = 6;
}
if (e.isShiftDown() == true) {
if (yy < ySize & yy > 100) {
shipY = yy - 16;
}
}
if (xx < xSize & xx > 1) {
shipX = xx - 16;
}
}
public void mouseMoved (MouseEvent e) {
int xx = e.getX();
int yy = e.getY();
if (yy < shipY - 32) {
speed = 9;
}
else {
speed = 6;
}
if (e.isShiftDown() == true) {
if (yy < ySize & yy > 100) {
shipY = yy - 16;
}
}
if (xx < xSize & xx > 1) {
shipX = xx - 16;
}
}
}
// This class handles mouse clicking and whether or not the mouse is in the game!
// Again if alt is down a different bullet is fired.
// I trap for all events that involve clicking and releasing the mouse button to ensure that the bullet is fired.
class LocalMouseListener implements MouseListener {
Star parent;
LocalMouseListener(Star p) {parent = p;}
public void mouseClicked (MouseEvent e) {
int r = 0;
if (gameover == true) {gameover = false;}
for (int a = 0; a < numBullets; a++) {
if (bOpen[a] == 0 & r == 0) {
if (e.isAltDown() == true) {
bType[a] = 2;
}
else {
bType[a] = 1;
}
bX[a] = shipX + 16;
bY[a] = shipY - 1;
bOpen[a] = 1;
r = 1;
}
}
}
public void mouseReleased (MouseEvent e) {
int r = 0;
if (gameover == true) {gameover = false;}
for (int a = 0; a < numBullets; a++) {
if (bOpen[a] == 0 & r == 0) {
if (e.isAltDown() == true) {
bType[a] = 2;
}
else {
bType[a] = 1;
}
bX[a] = shipX + 16;
bY[a] = shipY - 1;
bOpen[a] = 1;
r = 1;
}
}
}
public void mouseEntered (MouseEvent e) {out = 0;}
public void mouseExited (MouseEvent e) {out = 1;}
public void mousePressed (MouseEvent e) {
int r = 0;
if (gameover == true) {gameover = false;}
for (int a = 0; a < numBullets; a++) {
if (bOpen[a] == 0 & r == 0) {
if (e.isAltDown() == true) {
bType[a] = 2;
}
else {
bType[a] = 1;
}
bX[a] = shipX + 16;
bY[a] = shipY - 1;
bOpen[a] = 1;
r = 1;
}
}
}
}
}